# -*- coding: utf-8 -*-
from flask import render_template, g, request, session, redirect, url_for, current_app, jsonify

from info import constants, db
from info.models import User, News, Category
from info.utils.common import user_login_data
from info.utils.image_storage import storage
from info.utils.response_code import RET
from . import admin_blue
import time
from datetime import datetime, timedelta

"""增加新闻分类"""


@admin_blue.route("/add_category", methods=["GET", "POST"])
def add_category():
    # 从前端获取增加的新闻分类名
    category_name = request.json.get("name")
    cid = request.json.get("id")
    if not cid:
        category = Category()
        category.name=category_name
        db.session.add(category)
    else:
        category = Category.query.get(cid)
        category.name = category_name

    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,errmsg = "数据提交失败")

    return jsonify(errno=RET.OK, errmsg="ok")


"""新闻分类"""


@admin_blue.route("/news_type")
def news_type():
    categorys = Category.query.all()
    categorys_list = []
    for category in categorys:
        categorys_list.append(category.to_dict())

    categorys_list.pop(0)

    data = {
        "categories": categorys_list
    }
    return render_template("admin/news_type.html", data=data)


"""新闻编辑详情"""


@admin_blue.route("/news_edit_detail", methods=["GET", "POST"])
def news_edit_detail():
    if request.method == "GET":
        # 从前端获取需要编辑的新闻id
        news_id = request.args.get("news_id")
        # 查询到这个新闻的对象
        news = News.query.get(news_id)
        if not news:
            return jsonify(errno=RET.PARAMERR, errmsg="没有当前新闻")
        # 查询所有的新闻类
        categories = Category.query.all()
        categories_list = []
        # 把所有的新闻类转成字典添加到列表
        for categorie in categories:
            categories_list.append(categorie.to_dict())
        categories_list.pop(0)  # 没有最新类，所以把第一个元素删除
        data = {
            "categories": categories_list,
            "news": news.to_dict()
        }

        return render_template("admin/news_edit_detail.html", data=data)

    # 走到这里就是post表单提交，需要从前端获取表单数据
    news_id = request.form.get("news_id")
    title = request.form.get("title")
    category_id = request.form.get("category_id")
    digest = request.form.get("digest")
    index_image = request.files.get("index_image")
    content = request.form.get("content")
    if not all([category_id, digest, content, title]):
        return jsonify(errno=RET.PARAMERR, errmsg="请输入完整参数")
    try:
        index_image = index_image.read()
        key = storage(index_image)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg="第三方系统错误")
    try:
        # 找到当前新闻对象
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
    if not news:
        return jsonify(errno=RET.PARAMERR, errmsg="未查询到新闻数据")
    # 把编辑后的数据添加到新闻对象中
    news.title = title
    news.category_id = category_id
    news.digest = digest
    news.index_image = constants.QINIU_DOMIN_PREFIX + key
    news.content = content

    db.session.commit()

    return jsonify(errno=RET.OK, errmsg="ok")


"""新闻编辑"""


@admin_blue.route("/news_edit")
def news_edit():
    # 获取当前页面
    page = request.args.get("p", 1)
    try:
        page = int(page)
    except Exception as e:
        current_app.logger.error(e)
        page = 1
    # 获取所有的新闻列表
    paginate = News.query.order_by(News.create_time.desc()).paginate(page, constants.ADMIN_NEWS_PAGE_MAX_COUNT, False)
    items = paginate.items
    current_page = paginate.page
    totle_page = paginate.pages
    news_list = []
    for item in items:
        news_list.append(item.to_review_dict())

    data = {
        "news_list": news_list,
        "current_page": current_page,
        "totle_page": totle_page
    }
    return render_template("admin/news_edit.html", data=data)


"""新闻审核详情"""


@admin_blue.route("/news_review_detail", methods=["GET", "POST"])
def news_review_detail():
    if request.method == "GET":
        news_id = request.args.get("news_id")
        news = News.query.get(news_id)
        data = {
            "news": news.to_dict() if news else None
        }
        # 请求的时候展示审核详情页面
        return render_template("admin/news_review_detail.html", data=data)
    # 从前端获取表单数据

    action = request.json.get("action")
    news_id = request.json.get("news_id")
    if not all([action, news_id]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    news = News.query.get(news_id)
    if not news:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    if action not in ("accept", "reject"):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    if action == "accept":
        # 表示通过
        news.status = 0

    else:
        # 表示不通过
        news.status = -1
        # 审核不通过的原因
        reason = request.json.get("reason")
        if not reason:
            return jsonify(errno=RET.PARAMERR, errmsg="请说明没有通过的原因")
        news.reason = reason
    db.session.commit()
    return jsonify(errno=RET.OK, errmsg="ok")


"""后台新闻审核"""


@admin_blue.route("/news_review")
def news_review():
    # 从前端获取当前页面
    page = request.args.get("p", 1)
    # 从前端获取搜索的关键字
    keywords = request.args.get("keywords", None)
    # 对page进行异常抛出
    try:
        page = int(page)
    except Exception as e:
        current_app.logger.error(e)
        page = 1

    filters = [News.status != 0]
    if keywords:
        filters.append(News.title.contains(keywords))
    # 从数据库中获取所有需要审核的新闻
    paginate = News.query.filter(*filters).order_by(News.create_time.desc()).paginate(page,
                                                                                      constants.ADMIN_NEWS_PAGE_MAX_COUNT,
                                                                                      False)
    # 获取所有对象
    items = paginate.items
    # 获取当前页
    current_page = paginate.page
    # 获取总页数
    totle_page = paginate.pages
    news_list = []
    for item in items:
        news_list.append(item.to_review_dict())

    data = {
        "current_page": current_page,
        "total_page": totle_page,
        "news_list": news_list
    }
    return render_template("admin/news_review.html", data=data)


"""后台新闻列表"""


@admin_blue.route("/user_list")
def user_list():
    # 从前端获取当前页
    page = request.args.get("p", 1)
    # 对page进行异常处理
    try:
        page = int(page)
    except Exception as e:
        current_app.logger.error(e)
        page = 1
    # 查看所有用户对象并分页
    paginate = User.query.filter(User.is_admin == 0).order_by(User.create_time.desc()).paginate(page,
                                                                                                constants.ADMIN_USER_PAGE_MAX_COUNT,
                                                                                                False)
    # 获取所有对象
    items = paginate.items
    # 获取当前页
    current_page = paginate.page
    # 获取总页数
    total_page = paginate.pages
    user_list = []
    # 遍历列表
    for item in items:
        user_list.append(item.to_admin_dict())

    data = {
        "users": user_list,
        "current_page": current_page,
        "total_page": total_page
    }
    return render_template("admin/user_list.html", data=data)


"""后台首页"""


# @admin_blue.route("/index")
# @user_login_data
# def admin_index():
#     # 获取用户登陆信息，
#     user = g.user
#     # 前端是alt = "{{ user.nick_name }}，所以需要传值user
#     return render_template("admin/index.html", user=user.to_dict())
@admin_blue.route("/index")
@user_login_data
def admin_index():
    user = g.user
    return render_template("admin/index.html", user=user.to_dict())


"""后台登陆页面"""


# @admin_blue.route("/login", methods=["GET", "POST"])
# def admin_login():
#     # 1.如果是get请求首先需要跳转到登陆页面
#     if request.method == "GET":
#         return render_template("admin/login.html")
#     # 2.1如果是post请求，就需要从后台form表单获取数据
#     username = request.form.get("username")
#     password = request.form.get("password")
#     # 2.2从数据库中查询该用户是不是管理员,先按照管理员的标准查询到该用户，再判断该用户是不是存在，要是存在就是管理员
#     user = User.query.filter(User.mobile == username, User.is_admin == True).first()
#     # 2.3如果没有该用户就直接跳转到登陆页面，并且返回一个errmsg（注意看前端的代码）
#     if not user:
#         return render_template("admin/login.html",errmsg = "用户不存在")
#     # 2.4判断用户的密码是否正确
#     if not user.check_password(password):
#         return render_template("admin/login.html",errmsg="密码错误")
#     # 2.5代码走到这里说明管理员验证通过，就把相关信息存储到session中：
#     session["user_id"]=user.id
#     session["mobile"]=user.mobile
#     session["nick_name"]=user.nick_name
#     session["is_admin"]=user.is_admin
#     # 2. 如果登陆成功就直接跳刀首页
#     return redirect(url_for("admin.admin_index"))

@admin_blue.route("/login", methods=["GET", "POST"])
def admin_login():
    if request.method == "GET":
        user_id = session.get("user_id", None)
        is_admin = session.get("is_admin", False)
        if user_id and is_admin:
            return redirect(url_for("admin.admin_index"))

        return render_template("admin/login.html")
    # post请求,从前端获取表单数据
    username = request.form.get("username")
    password = request.form.get("password")
    # 在数据库中以管理员标准查找该用户
    user = User.query.filter(User.mobile == username, User.is_admin == 1).first()
    if not user:
        return render_template("admin/login.html", errmsg="没有当前用户")
    if not user.check_password(password):
        return render_template("admin/login.html", errmsg="密码错误")
    session["nick_name"] = user.nick_name
    session["mobile"] = user.mobile
    session["user_id"] = user.id
    session["is_admin"] = user.is_admin

    # 登陆成功需要跳转到后台首页,需要加上蓝图的名字admin
    return redirect(url_for("admin.admin_index"))


"""后台数据统计"""


@admin_blue.route("/user_count")
def user_count():
    # 用户总数
    total_count = 0
    # 用户月新增人数
    mon_count = 0
    # 用户日新增人数
    day_count = 0
    # 从数据库找到当前用户总数，除去管理员
    total_count = User.query.filter(User.is_admin == 0).count()

    # 查询到当前时间
    now = time.localtime()
    # 获取到月初时间
    mon_begin = "%d-%02d-01" % (now.tm_year, now.tm_mon)
    # 获取到月初精确时间，并且以标准格式的形式展出
    mon_begin_date = datetime.strptime(mon_begin, "%Y-%m-%d")

    # 查询到当月新增人数
    mon_count = User.query.filter(User.is_admin == 0, User.create_time >= mon_begin_date).count()
    # 查询到当日新增人数
    day_begin = "%d-%02d-%02d" % (now.tm_year, now.tm_mon, now.tm_mday)
    # 获取到今天的开始时间
    day_begin_date = datetime.strptime(day_begin, "%Y-%m-%d")
    # 查询到今天的新增的用户数量
    day_count = User.query.filter(User.is_admin == 0, User.create_time >= day_begin_date).count()
    # 查询一个月的每天的活跃人数
    now = time.localtime()
    # 获取今天的起始时间
    today_begin = "%d-%02d-%02d" % (now.tm_year, now.tm_mon, now.tm_mday)
    # 获取今天精确的起始时间及标准化
    today_begin_date = datetime.strptime(today_begin, "%Y-%m-%d")
    active_count = []
    active_time = []

    for i in range(0, 30):
        # 算出每一天的时间差，今天到起始时间
        today_begin_time = today_begin_date - timedelta(days=i)
        # 每天结束时间
        today_last_time = today_begin_date - timedelta(days=(i - 1))
        # 查询出每天创建的人数
        today_count = User.query.filter(User.is_admin == 0, User.create_time >= today_begin_time,
                                        User.create_time < today_last_time).count()
        # 把每天创建的数量添加到一个月的列表中
        active_count.append(today_count)
        active_time.append(today_begin_time.strftime("%Y-%m-%d"))
    active_count.reverse()
    active_time.reverse()
    data = {
        "total_count": total_count,
        "mon_count": mon_count,
        "day_count": day_count,
        "active_count": active_count,
        "active_time": active_time
    }
    return render_template("admin/user_count.html", data=data)
